home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / ACORNUSERS / EMULATOR / V2600 / !v2600 / c / raster < prev    next >
Text File  |  1998-04-10  |  18KB  |  906 lines

  1. /****************************************************************************
  2.  
  3.    This file is part of x2600, the Atari 2600 Emulator
  4.    ===================================================
  5.  
  6.    Copyright 1996 Alex Hornby. For contributions see the file CREDITS.
  7.  
  8.    This software is distributed under the terms of the GNU General Public
  9.    License. This is free software with ABSOLUTELY NO WARRANTY.
  10.  
  11.    See the file COPYING for Details.
  12.  
  13.    $Id: raster.c,v 1.25 1996/11/24 16:55:40 ahornby Exp $
  14. ****************************************************************************/
  15.  
  16. /* Raster graphics procedures */
  17.  
  18. #include "config.h"
  19. #include "string.h"
  20.  
  21. #include <stdio.h>
  22. #include "types.h"
  23. #include "address.h"
  24. #include "vmachine.h"
  25. #include "display.h"
  26. #include "collision.h"
  27.  
  28. /* Color lookup tables. Used to speed up rendering */
  29. /* The current colour lookup table */
  30. int *colour_lookup;
  31.  
  32. /* Colour table */
  33. #define P0M0_COLOUR 0
  34. #define P1M1_COLOUR 1
  35. #define PFBL_COLOUR 2
  36. #define BK_COLOUR 3
  37. BYTE colour_table[4];
  38.  
  39. /* normal/alternate, not scores/scores*/
  40. int norm_val, scores_val;
  41. int *colour_ptrs[2][3];
  42.  
  43. /* Normal priority */
  44. static int colour_normal[64];
  45. static int colour_normscoresl[64];
  46. static int colour_normscoresr[64];
  47.  
  48. /* Alternate priority */
  49. static int colour_alternate[64];
  50. static int colour_altscoresl[64];
  51. static int colour_altscoresr[64];
  52.  
  53. /* Playfield screen position */
  54. UINT32 *pf_pos;
  55. BYTE *line_ptr;
  56. BYTE bkc;
  57.  
  58. /* Draw playfield register PF0 */
  59. /* pf: playfield structure */
  60. /* dir: 1=normal, 0=mirrored */
  61. inline void
  62. draw_pf0 (struct PlayField *pf, int dir)
  63. {
  64.   int pfm;            /* playfield mask */
  65.   /* 1=forward */
  66.   if (dir)
  67.     {
  68.       for (pfm = 0x10; pfm < 0x100; pfm <<= 1)
  69.     {
  70.       if (pf->pf0 & pfm)
  71.         *(pf_pos++) = PF_MASK32;
  72.       else
  73.         pf_pos++;
  74.     }
  75.     }
  76.   else
  77.     {
  78.       for (pfm = 0x80; pfm > 0x08; pfm >>= 1)
  79.     {
  80.       if (pf->pf0 & pfm)
  81.         *(pf_pos++) = PF_MASK32;
  82.       else
  83.         pf_pos++;
  84.     }
  85.     }
  86. }
  87.  
  88. /* Draw playfield register PF1 */
  89. /* pf: playfield structure */
  90. /* dir: 1=normal, 0=mirrored */
  91. inline void
  92. draw_pf1 (struct PlayField *pf, int dir)
  93. {
  94.   int pfm;            /* playfield mask */
  95.   /* 1=forward */
  96.   if (dir)
  97.     {
  98.       /* do PF1 */
  99.       for (pfm = 0x80; pfm > 0; pfm >>= 1)
  100.     {
  101.       if (pf->pf1 & pfm)
  102.         *(pf_pos++) = PF_MASK32;
  103.       else
  104.         pf_pos ++;
  105.     }
  106.     }
  107.   else
  108.     {
  109.       /* do PF1 */
  110.       for (pfm = 0x01; pfm < 0x100; pfm <<= 1)
  111.     {
  112.       if (pf->pf1 & pfm)
  113.         *(pf_pos++) = PF_MASK32;
  114.       else
  115.         pf_pos ++;
  116.     }
  117.     }
  118. }
  119.  
  120. /* Draw playfield register PF2 */
  121. /* pf: playfield structure */
  122. /* dir: 1=normal, 0=mirrored */
  123. inline void
  124. draw_pf2 (struct PlayField *pf, int dir)
  125. {
  126.   int pfm;            /* playfield mask */
  127.   /* 1=forward */
  128.   if (dir)
  129.     {
  130.       /* do PF2 */
  131.       for (pfm = 0x01; pfm < 0x100; pfm <<= 1)
  132.     {
  133.       if (pf->pf2 & pfm)
  134.         *(pf_pos++) = PF_MASK32;
  135.       else
  136.         pf_pos ++;
  137.     }
  138.     }
  139.   else
  140.     {
  141.       for (pfm = 0x80; pfm > 0; pfm >>= 1)
  142.     {
  143.       if (pf->pf2 & pfm)
  144.         *(pf_pos++) = PF_MASK32;
  145.       else
  146.         pf_pos ++;
  147.     }
  148.     }
  149. }
  150.  
  151. /* Update from the playfield display list */
  152. /* num: playfield to use. Now depreciated as only pf[0] is used */
  153. /* nextx: the start position of the next playfield element */
  154. /* pfc: the number of the next playfield change structure */
  155. /* pf_max: the highest playfield change structure */
  156. inline void
  157. pf_update (int num, int nextx, int *pfc, int pf_max)
  158. {
  159.   for (; (*pfc < pf_max) && (nextx + 3 > pf_change[num][*pfc].x); (*pfc)++)
  160.     {
  161.       use_pfraster_change (&pf[num], &pf_change[num][*pfc]);
  162.     }
  163. }
  164.  
  165. /* Draw the playfield */
  166. void
  167. draw_playfield (void)
  168. {
  169.   const int num = 0;        /* Stick to one playfield */
  170.   int pfc = 0;
  171.   int pf_max = pf_change_count[num];
  172.  
  173.   pf_pos = (UINT32 *)colvect;
  174.   /* First half of playfield */
  175.  
  176.   pf_update (num, 0, &pfc, pf_max);
  177.   draw_pf0 (&pf[0], 1);
  178.   pf_update (num, 16, &pfc, pf_max);
  179.   draw_pf1 (&pf[0], 1);
  180.   pf_update (num, 48, &pfc, pf_max);
  181.   draw_pf2 (&pf[0], 1);
  182.  
  183.   pf_update (num, 80, &pfc, pf_max);
  184.   /* Second half of playfield */
  185.   if (pf[0].ref)
  186.     {
  187.       draw_pf2 (&pf[0], 0);
  188.       pf_update (num, 112, &pfc, pf_max);
  189.       draw_pf1 (&pf[0], 0);
  190.       pf_update (num, 144, &pfc, pf_max);
  191.       draw_pf0 (&pf[0], 0);
  192.     }
  193.   else
  194.     {
  195.       draw_pf0 (&pf[0], 1);
  196.       pf_update (num, 96, &pfc, pf_max);
  197.       draw_pf1 (&pf[0], 1);
  198.       pf_update (num, 128, &pfc, pf_max);
  199.       draw_pf2 (&pf[0], 1);
  200.     }
  201.   /* Use last changes */
  202.   if(pfc < pf_max){
  203.     pfc++;
  204.     use_pfraster_change (&pf[num], &pf_change[num][pfc]);
  205.   }
  206.  
  207.   pf_change_count[num] = 0;
  208. }
  209.  
  210. /* Draws a normal (8 clocks) sized player */
  211. /* p: the player to draw */
  212. /* x: the position to draw it */
  213. inline void
  214. pl_normal (struct Player *p, int x)
  215. {
  216.   /* Set pointer to start of player graphic */
  217.   BYTE *ptr = colvect + x;
  218.   BYTE mask;
  219.   BYTE gr;
  220.  
  221.   if (p->vdel_flag)
  222.     gr = p->vdel;
  223.   else
  224.     gr = p->grp;
  225.  
  226.   if (p->reflect)
  227.     {
  228.       /* Reflected: start with D0 of GRP on left */
  229.       for (mask = 0x01; mask > 0; mask <<= 1)
  230.     {
  231.       if (gr & mask)
  232.         {
  233.           *(ptr++) |= p->mask;
  234.         }
  235.       else
  236.         ptr++;
  237.     }
  238.     }
  239.   else
  240.     {
  241.       /* Unreflected: start with D7 of GRP on left */
  242.       for (mask = 0x80; mask > 0; mask >>= 1)
  243.     {
  244.       if (gr & mask)
  245.         {
  246.           *(ptr++) |= p->mask;
  247.         }
  248.       else
  249.         ptr++;
  250.     }
  251.     }
  252. }
  253.  
  254. /* Draws a double width ( 16 clocks ) player */
  255. /* p: the player to draw */
  256. /* x: the position to draw it */
  257. inline void
  258. pl_double (struct Player *p, int x)
  259. {
  260.   /* Set pointer to start of player graphic */
  261.   BYTE *ptr = colvect + (x);
  262.   BYTE mask;
  263.   BYTE gr;
  264.  
  265.   if (p->vdel_flag)
  266.     gr = p->vdel;
  267.   else
  268.     gr = p->grp;
  269.  
  270.   if (p->reflect)
  271.     {
  272.       for (mask = 0x01; mask > 0; mask <<= 1)
  273.     {
  274.       if (gr & mask)
  275.         {
  276.           *(ptr++) |= p->mask;
  277.           *(ptr++) |= p->mask;
  278.         }
  279.       else
  280.         ptr += 2;
  281.     }
  282.     }
  283.   else
  284.     {
  285.       for (mask = 0x80; mask > 0; mask >>= 1)
  286.     {
  287.       if (gr & mask)
  288.         {
  289.           *(ptr++) |= p->mask;
  290.           *(ptr++) |= p->mask;
  291.         }
  292.       else
  293.         ptr += 2;
  294.     }
  295.     }
  296. }
  297.  
  298. /* Draws a quad sized ( 32 clocks) player */
  299. /* p: the player to draw */
  300. /* x: the position to draw it */
  301. inline void
  302. pl_quad (struct Player *p, int x)
  303. {
  304.   /* Set pointer to start of player graphic */
  305.   BYTE *ptr = colvect + x;
  306.   BYTE mask;
  307.   BYTE gr;
  308.  
  309.   if (p->vdel_flag)
  310.     gr = p->vdel;
  311.   else
  312.     gr = p->grp;
  313.  
  314.   if (p->reflect)
  315.     {
  316.       for (mask = 0x01; mask > 0; mask <<= 1)
  317.     {
  318.       if (gr & mask)
  319.         {
  320.           *(ptr++) |= p->mask;
  321.           *(ptr++) |= p->mask;
  322.           *(ptr++) |= p->mask;
  323.           *(ptr++) |= p->mask;
  324.         }
  325.       else
  326.         ptr += 4;
  327.     }
  328.     }
  329.   else
  330.     {
  331.       for (mask = 0x80; mask > 0; mask >>= 1)
  332.     {
  333.       if (gr & mask)
  334.         {
  335.           *(ptr++) |= p->mask;
  336.           *(ptr++) |= p->mask;
  337.           *(ptr++) |= p->mask;
  338.           *(ptr++) |= p->mask;
  339.         }
  340.       else
  341.         ptr += 4;
  342.     }
  343.     }
  344. }
  345.  
  346. /* Consume the player display list */
  347. inline void
  348. pl_update (int num, int nextx, int *plc, int pl_max)
  349. {
  350.   for (; (*plc < pl_max) && (nextx > pl_change[num][*plc].x); (*plc)++)
  351.     {
  352.       use_plraster_change (&pl[num], &pl_change[num][*plc]);
  353.     }
  354. }
  355.  
  356. /* Draw a player graphic */
  357. /* line: the vertical position of the raster */
  358. /* num: the number of player to draw, current 0 or 1 for P0 and P1 */
  359. static inline void
  360. pl_draw (int num)
  361. {
  362.   int plc = 0;
  363.   int pl_max = pl_change_count[num];
  364.   int nextx;
  365.  
  366.   pl_update (num, pl[num].x, &plc, pl_max);
  367.   if (pl[num].x >= 0 && pl[num].x < tv_width)
  368.     {
  369.  
  370.       /*if(pl_max > plc)
  371.          use_plraster_change( &pl[num], &pl_change[num][plc++]); */
  372.       switch (pl[num].nusize)
  373.     {
  374.     case 0:
  375.       /* One copy */
  376.       pl_normal (&pl[num], pl[num].x);
  377.       break;
  378.     case 1:
  379.       /* Two copies close */
  380.       pl_normal (&pl[num], pl[num].x);
  381.       nextx = pl[num].x + 8 + 8;
  382.       pl_update (num, nextx, &plc, pl_max);
  383.       pl_normal (&pl[num], nextx);
  384.       break;
  385.     case 2:
  386.       /* Two copies medium */
  387.       pl_normal (&pl[num], pl[num].x);
  388.       nextx = pl[num].x + 8 + 24;
  389.       pl_update (num, nextx, &plc, pl_max);
  390.       pl_normal (&pl[num], nextx);
  391.       break;
  392.     case 3:
  393.       /* Three copies close */
  394.       /* Pacman score line */
  395.       pl_normal (&pl[num], pl[num].x);
  396.  
  397.       nextx = pl[num].x + 16;
  398.       pl_update (num, nextx, &plc, pl_max);
  399.       pl_normal (&pl[num], nextx);
  400.  
  401.       nextx = pl[num].x + 32;
  402.       pl_update (num, nextx, &plc, pl_max);
  403.  
  404.       pl_normal (&pl[num], nextx);
  405.       break;
  406.     case 4:
  407.       /* Two copies wide */
  408.       pl_normal (&pl[num], pl[num].x);
  409.       nextx = pl[num].x + 8 + 56;
  410.       pl_update (num, nextx, &plc, pl_max);
  411.       pl_normal (&pl[num], nextx);
  412.       break;
  413.     case 5:
  414.       /* Double sized player */
  415.       pl_double (&pl[num], pl[num].x);
  416.       break;
  417.     case 6:
  418.       /* Three copies medium */
  419.       pl_normal (&pl[num], pl[num].x);
  420.       nextx = pl[num].x + 8 + 24;
  421.       pl_update (num, nextx, &plc, pl_max);
  422.       pl_normal (&pl[num], nextx);
  423.       nextx = pl[num].x + 8 + 56;
  424.       pl_update (num, nextx, &plc, pl_max);
  425.       pl_normal (&pl[num], nextx);
  426.       break;
  427.     case 7:
  428.       /* Quad sized player */
  429.       pl_quad (&pl[num], pl[num].x);
  430.       break;
  431.     }
  432.     }
  433.   /* Use last changes */
  434.   for (; plc < pl_max; plc++)
  435.     use_plraster_change (&pl[num], &pl_change[num][plc]);
  436.   pl_change_count[num] = 0;
  437. }
  438.  
  439.  
  440. /* Draw the ball graphic */
  441. /* line: the vertical position of the raster */
  442. static inline void
  443. draw_ball (void)
  444. {
  445.   int i;
  446.   BYTE *blptr;
  447.   BYTE e;
  448.  
  449.   if (ml[2].vdel_flag)
  450.     e = ml[2].vdel;
  451.   else
  452.     e = ml[2].enabled;
  453.  
  454.   if (e && ml[2].x >= 0)
  455.     {
  456.       blptr = colvect + (ml[2].x);
  457.       switch (tiaWrite[CTRLPF] >> 4)
  458.     {
  459.     case 3:
  460.       /* Eight clocks */
  461.       for (i = 0; i < 8; i++)
  462.         *(blptr++) |= BL_MASK;
  463.       break;
  464.     case 2:
  465.       /* Four clocks */
  466.       for (i = 0; i < 4; i++)
  467.         *(blptr++) |= BL_MASK;
  468.       break;
  469.     case 1:
  470.       /* Two clocks */
  471.       for (i = 0; i < 2; i++)
  472.         *(blptr++) |= BL_MASK;
  473.       break;
  474.     case 0:
  475.       /* One clock */
  476.       *(blptr++) |= BL_MASK;
  477.       break;
  478.     }
  479.     }
  480. }
  481.  
  482.  
  483. /* Draw a missile graphic */
  484. static inline void
  485. do_missile (int num, BYTE * misptr)
  486. {
  487.   int i;
  488.  
  489.   misptr = colvect + (ml[num].x);
  490.   switch (ml[num].width)
  491.     {
  492.     case 0:
  493.       /* one clock */
  494.       *(misptr++) |= ml[num].mask;
  495.       break;
  496.     case 1:
  497.       /* two clocks */
  498.       for (i = 0; i < 2; i++)
  499.     *(misptr++) |= ml[num].mask;
  500.       break;
  501.     case 2:
  502.       /* four clocks */
  503.       for (i = 0; i < 4; i++)
  504.     *(misptr++) |= ml[num].mask;
  505.       break;
  506.     case 3:
  507.       /* Eight clocks */
  508.       for (i = 0; i < 8; i++)
  509.     *(misptr++) |= ml[num].mask;
  510.       break;
  511.     }                /* switch */
  512. }
  513.  
  514. /* Draw a missile taking into account the player's position. */
  515. /* line: the vertical position of the raster */
  516. /* num: 0 for M0, 1 for M1 */
  517. static inline void
  518. draw_missile (int num)
  519. {
  520.   BYTE *misptr;
  521.  
  522.   if (ml[num].enabled && ml[num].x >= 0)
  523.     {
  524.       switch (pl[num].nusize)
  525.     {
  526.     case 0:
  527.       misptr = colvect + (ml[num].x);
  528.       do_missile (num, misptr);
  529.       break;
  530.     case 1:
  531.       misptr = colvect + (ml[num].x);
  532.       do_missile (num, misptr);
  533.       misptr = misptr + 16;
  534.       do_missile (num, misptr);
  535.       break;
  536.     case 2:
  537.       misptr = colvect + (ml[num].x);
  538.       do_missile (num, misptr);
  539.       misptr = misptr + 32;
  540.       do_missile (num, misptr);
  541.       break;
  542.     case 3:
  543.       misptr = colvect + (ml[num].x);
  544.       do_missile (num, misptr);
  545.       misptr = misptr + 16;
  546.       do_missile (num, misptr);
  547.       misptr = misptr + 16;
  548.       do_missile (num, misptr);
  549.       break;
  550.     case 4:
  551.       misptr = colvect + (ml[num].x);
  552.       do_missile (num, misptr);
  553.       misptr = misptr + 64;
  554.       do_missile (num, misptr);
  555.       break;
  556.     case 5:
  557.       misptr = colvect + (ml[num].x);
  558.       do_missile (num, misptr);
  559.       break;
  560.     case 6:
  561.       misptr = colvect + (ml[num].x);
  562.       do_missile (num, misptr);
  563.       misptr = misptr + 32;
  564.       do_missile (num, misptr);
  565.       misptr = misptr + 32;
  566.       do_missile (num, misptr);
  567.       break;
  568.     case 7:
  569.       misptr = colvect + (ml[num].x);
  570.       do_missile (num, misptr);
  571.       break;
  572.     }
  573.     }                /* If */
  574. }
  575.  
  576.  
  577. /* Construct one tv raster line colvect */
  578. /* line: the vertical position of the raster */
  579. void
  580. tv_rasterise (int line)
  581. {
  582.   line_ptr = vscreen + line * vwidth;
  583.  
  584.   /* Draw the playfield first */
  585.   draw_playfield ();
  586.  
  587.   /* Do the ball */
  588.   draw_ball ();
  589.  
  590.   /* Do the player 1 graphics */
  591.   draw_missile (1);
  592.   pl_draw (1);
  593.  
  594.   /* Do the player 0 graphics */
  595.   draw_missile (0);
  596.   pl_draw (0);
  597. }
  598.  
  599. /* Reset the collision vector */
  600. void
  601. reset_vector (void)
  602. {
  603.   int i;
  604.   UINT32 *cpos=(UINT32 *)colvect;
  605.   for (i = 0; i < 40; i++)
  606.     cpos[i] = 0;
  607. }
  608.  
  609.  
  610. /* draw the collision vector */
  611. /* Quick version with no magnification */
  612. void
  613. draw_vector_q (void)
  614. {
  615.   int i;
  616.   int uct = 0;
  617.   int colind, colval;
  618.   BYTE pad;
  619.   BYTE *tv_ptr = line_ptr;
  620.  
  621.   /* Check for scores */
  622.   if(scores_val ==2)
  623.     {
  624.       scores_val=1;
  625.       colour_lookup=colour_ptrs[norm_val][scores_val];
  626.     }
  627.  
  628.   /* Use starting changes */
  629.   while (uct < unified_count && unified[uct].x < 0)
  630.     use_unified_change (&unified[uct++]);
  631.  
  632.   for (i = 0; i < 80; i++)
  633.     {
  634.       if (uct < unified_count && unified[uct].x == i)
  635.     use_unified_change (&unified[uct++]);
  636.  
  637.       if((colval=colvect[i]) != 0){
  638.  
  639.     /* Collision detection */
  640.     col_state|=col_table[colval];
  641.  
  642.     colind=colour_lookup[colval];
  643.     pad=colour_table[colind];
  644.       } else
  645.     pad=colour_table[BK_COLOUR];
  646.  
  647.       *(tv_ptr++) = pad;
  648.       *(tv_ptr++) = pad;
  649.     }
  650.  
  651.   /* Check for scores */
  652.   if(scores_val ==1)
  653.     {
  654.       scores_val=2;
  655.       colour_lookup=colour_ptrs[norm_val][scores_val];
  656.     }
  657.   for (i = 80; i < 160; i++)
  658.     {
  659.       if (uct < unified_count && unified[uct].x == i)
  660.     use_unified_change (&unified[uct++]);
  661.  
  662.       if((colval=colvect[i]) != 0){
  663.  
  664.     /* Collision detection */
  665.     col_state|=col_table[colval];
  666.  
  667.     colind=colour_lookup[colval];
  668.     pad=colour_table[colind];
  669.       } else
  670.     pad=colour_table[BK_COLOUR];
  671.  
  672.       *(tv_ptr++) = pad;
  673.       *(tv_ptr++) = pad;
  674.     }
  675.  
  676.   while (uct < unified_count)
  677.     use_unified_change (&unified[uct++]);
  678.   unified_count = 0;
  679. }
  680.  
  681.  
  682. /* draw the collision vector */
  683. /* const agrument ensures that constant propagation occurs, meaning
  684.    less slow down for the magstep=1 case */
  685. void
  686. draw_vector(const int magstep)
  687. {
  688.   int i,j;
  689.   int uct = 0;
  690.   int colind, colval;
  691.   BYTE pad;
  692.   BYTE *tv_ptr = line_ptr;
  693.  
  694.   /* Check for scores */
  695.   if(scores_val ==2)
  696.     {
  697.       scores_val=1;
  698.       colour_lookup=colour_ptrs[norm_val][scores_val];
  699.     }
  700.  
  701.   /* Use starting changes */
  702.   while (uct < unified_count && unified[uct].x < 0)
  703.     use_unified_change (&unified[uct++]);
  704.  
  705.   for (i = 0; i < 80; i++)
  706.     {
  707.       if (uct < unified_count && unified[uct].x == i)
  708.     use_unified_change (&unified[uct++]);
  709.  
  710.       if((colval=colvect[i]) != 0){
  711.  
  712.     /* Collision detection */
  713.     col_state|=col_table[colval];
  714.  
  715.     colind=colour_lookup[colval];
  716.     pad=colour_table[colind];
  717.       } else
  718.     pad=colour_table[BK_COLOUR];
  719.  
  720.       for(j=0; j<magstep; j++)
  721.     {
  722.       *(tv_ptr++) = pad;
  723.       *(tv_ptr++) = pad;
  724.     }
  725.     }
  726.  
  727.   /* Check for scores */
  728.   if(scores_val ==1)
  729.     {
  730.       scores_val=2;
  731.       colour_lookup=colour_ptrs[norm_val][scores_val];
  732.     }
  733.   for (i = 80; i < 160; i++)
  734.     {
  735.       if (uct < unified_count && unified[uct].x == i)
  736.     use_unified_change (&unified[uct++]);
  737.  
  738.       if((colval=colvect[i]) != 0){
  739.  
  740.     /* Collision detection */
  741.     col_state|=col_table[colval];
  742.  
  743.     colind=colour_lookup[colval];
  744.     pad=colour_table[colind];
  745.       } else
  746.     pad=colour_table[BK_COLOUR];
  747.  
  748.       for(j=0; j<magstep; j++)
  749.     {
  750.       *(tv_ptr++) = pad;
  751.       *(tv_ptr++) = pad;
  752.     }
  753.     }
  754.  
  755.   while (uct < unified_count)
  756.     use_unified_change (&unified[uct++]);
  757.   unified_count = 0;
  758. }
  759.  
  760. /* Used for when running in frame skipping mode */
  761. static inline void
  762. update_registers (void)
  763. {
  764.   int i, num;
  765.  
  766.   /* Playfield */
  767.   for (i = 0; i < pf_change_count[0]; i++)
  768.     use_pfraster_change (&pf[0], &pf_change[0][i]);
  769.   pf_change_count[0] = 0;
  770.  
  771.   /* Player graphics */
  772.   for (num = 0; num < 2; num++)
  773.     {
  774.       for (i = 0; i < pl_change_count[num]; i++)
  775.     use_plraster_change (&pl[num], &pl_change[num][i]);
  776.       pl_change_count[num] = 0;
  777.     }
  778.  
  779.   /* Unified */
  780.   for (i = 0; i < unified_count; i++)
  781.     use_unified_change (&unified[i]);
  782.   unified_count = 0;
  783. }
  784.  
  785. /* Main raster function, will have switches for different magsteps */
  786. /* line: the vertical position of the raster */
  787. void
  788. tv_raster (int line)
  789. {
  790.   if (line > theight )
  791.     {
  792.       update_registers ();
  793.     }
  794.   else
  795.     {
  796.       reset_vector();
  797.       tv_rasterise (line);
  798.       draw_vector_q ();
  799.     }
  800. }
  801.  
  802.  
  803. void
  804. init_raster (void)
  805. {
  806.   int i,val;
  807.  
  808.   init_collisions();
  809.  
  810.   /* Normal Priority */
  811.   for (i=0; i<64; i++)
  812.     {
  813.       if (i & (PL0_MASK | ML0_MASK))
  814.     val = P0M0_COLOUR;
  815.       else if (i & (PL1_MASK | ML1_MASK))
  816.     val = P1M1_COLOUR;
  817.       else if (i & (BL_MASK | PF_MASK))
  818.     val = PFBL_COLOUR;
  819.       else
  820.     val = BK_COLOUR;
  821.       colour_normal[i]=val;
  822.     }
  823.  
  824.   /* Alternate Priority */
  825.   for (i=0; i<64; i++)
  826.     {
  827.       if (i & (BL_MASK | PF_MASK))
  828.     val = PFBL_COLOUR;
  829.       else if (i & (PL0_MASK | ML0_MASK))
  830.     val = P0M0_COLOUR;
  831.       else if (i & (PL1_MASK | ML1_MASK))
  832.     val = P1M1_COLOUR;
  833.       else
  834.     val = BK_COLOUR;
  835.       colour_alternate[i]=val;
  836.     }
  837.  
  838.   /* Normal Scores Left */
  839.   for (i=0; i<64; i++)
  840.     {
  841.       if (i & (PL0_MASK | ML0_MASK))
  842.     val = P0M0_COLOUR;
  843.       else if (i & (PL1_MASK | ML1_MASK))
  844.     val = P1M1_COLOUR;
  845.       else if (i & (BL_MASK | PF_MASK))
  846.     /* Use P1 colour */
  847.     val = P0M0_COLOUR;
  848.       else
  849.     val = BK_COLOUR;
  850.       colour_normscoresl[i]=val;
  851.     }
  852.  
  853.   /* Normal Scores Right */
  854.   for (i=0; i<64; i++)
  855.     {
  856.       if (i & (PL0_MASK | ML0_MASK))
  857.     val = P0M0_COLOUR;
  858.       else if (i & (PL1_MASK | ML1_MASK))
  859.     val = P1M1_COLOUR;
  860.       else if (i & (BL_MASK | PF_MASK))
  861.     /* Use P1 colour */
  862.     val = P1M1_COLOUR;
  863.       else
  864.     val = BK_COLOUR;
  865.       colour_normscoresr[i]=val;
  866.     }
  867.  
  868.   /* Alternate Scores Left*/
  869.   for (i=0; i<64; i++)
  870.     {
  871.       if (i & (BL_MASK | PF_MASK))
  872.     val = P0M0_COLOUR;
  873.       else if (i & (PL0_MASK | ML0_MASK))
  874.     val = P0M0_COLOUR;
  875.       else if (i & (PL1_MASK | ML1_MASK))
  876.     val = P1M1_COLOUR;
  877.       else
  878.     val = BK_COLOUR;
  879.       colour_altscoresl[i]=val;
  880.     }
  881.  
  882.   /* Alternate Scores Right*/
  883.   for (i=0; i<64; i++)
  884.     {
  885.       if (i & (BL_MASK | PF_MASK))
  886.     val = P1M1_COLOUR;
  887.       else if (i & (PL0_MASK | ML0_MASK))
  888.     val = P0M0_COLOUR;
  889.       else if (i & (PL1_MASK | ML1_MASK))
  890.     val = P1M1_COLOUR;
  891.       else
  892.     val = BK_COLOUR;
  893.       colour_altscoresr[i]=val;
  894.     }
  895.  
  896.   colour_ptrs[0][0]=colour_normal;
  897.   colour_ptrs[1][0]=colour_alternate;
  898.   colour_ptrs[0][1]=colour_normscoresl;
  899.   colour_ptrs[1][1]=colour_altscoresl;
  900.   colour_ptrs[0][2]=colour_normscoresr;
  901.   colour_ptrs[1][2]=colour_altscoresr;
  902.   norm_val=0; scores_val=0;
  903.  
  904.   colour_lookup=colour_normal;
  905. }
  906.